<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<script type="module">

// Used to notify an iframe to activate of activation ready.
const readyChannel = new BroadcastChannel('ready-channel');

// Used to notify the main test page of the test result.
const resultChannel = new BroadcastChannel('result-channel');

// URL to be prerendered.
const prerenderingUrl = new URL(document.URL);
prerenderingUrl.searchParams.set('mode', 'prerendering');

const params = new URLSearchParams(location.search);

try {
  // The `mode` param indicates the purpose of the loaded frame.
  switch (params.get('mode')) {
    // The main frame to trigger prerendering.
    case 'triggering': {
      assert_false(document.prerendering);

      // Create an iframe to activate a prerendered page instead of the main
      // frame.
      const iframeUrl = new URL(document.URL);
      iframeUrl.searchParams.set('mode', 'activating-from-iframe');
      // Wait for the iframe to be loaded. This prevents readyChannel messages
      // from being sent before the receiver side is ready.
      await createFrame(iframeUrl);
      startPrerendering(prerenderingUrl.toString());
      break;
    }

    // The iframe to initiate navigation on the main frame to activate the
    // prerendered page.
    case 'activating-from-iframe': {
      assert_false(document.prerendering);

      // Wait for activation ready.
      const gotMessage = await new Promise(r => readyChannel.onmessage = r);
      assert_equals(gotMessage.data, 'activation ready');
      resultChannel.postMessage('attempting prerender activation');

      // Initiate navigation on the main frame. This will attempt to prerender
      // a page from the iframe, but fail because the initiator of the
      // navigation will not match. The url will be loaded from scratch,
      // without prerendering.
      window.parent.location = prerenderingUrl.toString();

      // Close this iframe. This shouldn't cancel activation attempt.
      window.close();
      break;
    }

    // The main frame of the page being prerendered.
    case 'prerendering': {
      if (document.prerendering) {
        // Inform the activator iframe that this page is ready for activation.
        readyChannel.postMessage('activation ready');

        // Waiting for a confirmation of prerendering activation, which will
        // not come.
        await new Promise(r => document.onprerenderingchange = r);
      } else {
        // This block is executed when the page is loaded from scratch after
        // a failed prerender activation.
        // Inform the main test page that activation failed, but page was
        // loaded from scratch.
        resultChannel.postMessage('loaded from scratch');
      }
      break;
    }
  }
} catch (e) {
  resultChannel.postMessage(e.toString());
} finally {
  readyChannel.close();
  resultChannel.close();
}

</script>
